﻿using Futajma.MigrationStudio.DataDefinition;
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Futajma.MigrationStudio.CommonLib;
using Futajma.MigrationStudio.GenericPersistance;

namespace LLTreeManagementApplication.Dialog
{
    public partial class SpotTestCreation : Form
    {
        string _templatePath;
        bool _templateLoaded = false;
        ProjectParameter _projectParameter;

        Dictionary<string, KeyValuePair<string, string>> _spotTestList = new Dictionary<string, KeyValuePair<string, string>>();
        TreeView _source, _target;

        public SpotTestCreation()
        {
            InitializeComponent();

            txtRowNumber.Text = Settings.DefaultStartRowNumber;
            txtSourceUrlColumnName.Text = Settings.DefaultSourceUrlColumnName;
            txtTargteUrlColumnName.Text = Settings.DefaultTargetUrlColumnName;
            _projectParameter = null;

        }

        public DialogResult ShowDialog(TreeView source, TreeView target, ProjectParameter projectParameter)
        {
            _source = source;
            _target = target;
            _projectParameter = projectParameter;
            
            if (projectParameter.ProjectIsCommited || projectParameter.ProjectVersion == 0)
            {
                rbAll.Checked = true;
            }
            else
            {
                rbLatestImport.Checked = true;
            }
            
            return this.ShowDialog();
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            GenerateSpotTestList();
        }

        private void GenerateSpotTestList()
        {
            SaveFileDialog saveDlg = new SaveFileDialog();
            saveDlg.RestoreDirectory = true;
            saveDlg.Filter = "Excel File|*.xlsx";
            saveDlg.Title = "Select a test template file";

            if (saveDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                using (var ms = new MemoryStream())
                {
                    using (var templateFileInfo = new FileStream(_templatePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        ProjectPersistence.CopyStream(templateFileInfo, ms);
                        templateFileInfo.Close();
                    }
                    _spotTestList.Clear();

                    int projectVersion = 0;

                    if (rbLatestImport.Checked)
                    {
                        projectVersion = _projectParameter.ProjectVersion;
                        if (_projectParameter.ProjectIsCommited)
                        {
                            projectVersion = projectVersion - 1;
                        }
                    }

                    foreach (TreeNode node in _target.Nodes[0].Nodes)
                    {
                        ProcessTreeNode(node, false, projectVersion);
                    }

                    var list = GetRandomList();

                    //using (var templateFileInfo = new FileStream(_templatePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    //{
                    using (var saveFileInfo = new FileStream(saveDlg.FileName, FileMode.Create))
                    {
                        using (var excel = new ExcelPackage(saveFileInfo, ms))
                        {

                            ExcelWorksheet worksheet = excel.Workbook.Worksheets[(string)cbxWorksheets.SelectedItem];

                            int row = 1;
                            int.TryParse(txtRowNumber.Text, out row);

                            foreach (var item in list)
                            {
                                worksheet.Cells[string.Format("{0}{1}", txtSourceUrlColumnName.Text, row)].Value = item.Key;
                                worksheet.Cells[string.Format("{0}{1}", txtTargteUrlColumnName.Text, row)].Value = item.Value;
                                row++;
                            }
                            excel.Save();
                            excel.Dispose();
                        }
                        saveFileInfo.Dispose();
                    }
                    MessageBox.Show(string.Format("{0} spot test(s) sucessfull created.", list.Count()));
                }
            }
        }

        IEnumerable<KeyValuePair<string, string>> GetRandomList()
        {
            var testCoveage = 0;
            int.TryParse(txtTestCoverage.Text, out testCoveage);

            if (testCoveage <= 100)
            {
                var percent = _spotTestList.Count * testCoveage / 100;

                return _spotTestList.Values.ToList().Shuffle().Take(percent);
            }
            else
            {
                return _spotTestList.Values.ToList();
            }
        }

        private void ProcessTreeNode(TreeNode node, bool flattenStructure, int projectVersion)
        {
            var data = node.Tag as DataNode;

            if (data.SharePointType == SharePointType.DocLibrary)
            {
                flattenStructure = data.RemoveFolderStructure;
            }

            if (data.SharePointType != SharePointType.Item && data.SharePointType != SharePointType.Document)
            {
                if (cbxFullExport.Checked && !flattenStructure)
                {
                    var targetPath = GeneratePath(node, flattenStructure);
                    var sourceId = string.IsNullOrEmpty(data.SourceId) ? targetPath : data.SourceId;
                    if (data.Version >= projectVersion)
                    {
                        if (_spotTestList.ContainsKey(sourceId))
                        {
                            MessageBox.Show(string.Format("{0} is used as path more than once in the tree. Please execute validation first and clean up your tree", sourceId));
                        }
                        else
                        {
                            _spotTestList.Add(sourceId, new KeyValuePair<string, string>(data.SourceUrl, targetPath));
                        }
                    }
                }
            }
            else
            {
                var targetPath = GeneratePath(node, flattenStructure);
                var sourceId = string.IsNullOrEmpty(data.SourceId) ? targetPath : data.SourceId;

                if (data.Version >= projectVersion)
                {
                    _spotTestList.Add(sourceId, new KeyValuePair<string, string>(data.SourceUrl, targetPath));
                }
            }

            foreach (TreeNode child in node.Nodes)
            {
                ProcessTreeNode(child, flattenStructure, projectVersion);
            }

        }

        private string GeneratePath(TreeNode node, bool flattenStructure)
        {
            var data = node.Tag as DataNode;

            if (node.Parent != null)
            {
                if (flattenStructure)
                {
                    if (data.SharePointType == SharePointType.Folder)
                    {
                        return GeneratePath(node.Parent, flattenStructure);
                    }
                }

                if (data.SharePointType == SharePointType.SiteCollection)
                {
                    return data.TargetPath;
                    //return string.Format("{0}/{1}", data.TargetPath, node.Text);
                }
                else if (data.SharePointType == SharePointType.Site && !string.IsNullOrEmpty(data.TargetPath))
                {
                    return string.Format("{0}/{1}", GeneratePath(node.Parent, flattenStructure), data.TargetPath);
                }
                else if (data.SharePointType == SharePointType.DocLibrary && !string.IsNullOrEmpty(data.TargetPath))
                {
                    return string.Format("{0}/{1}", GeneratePath(node.Parent, flattenStructure), data.TargetPath);
                }
                else
                {
                    return string.Format("{0}/{1}", GeneratePath(node.Parent, flattenStructure), node.Text);
                }
            }
            else
            {
                if (data.SharePointType != SharePointType.Application)
                {
                    return node.Text;
                }
                else
                {
                    return string.Empty;
                }
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = System.Windows.Forms.DialogResult.Cancel;
        }

        private void txtTestCoverage_Leave(object sender, EventArgs e)
        {
            int val = 0;
            int.TryParse(txtTestCoverage.Text, out val);

            if (val > 100)
            {
                val = 100;
            }

            if (val < 0)
            {
                val = 0;
            }

            txtTestCoverage.Text = val.ToString();

        }

        private void txtTestCoverage_TextChanged(object sender, EventArgs e)
        {
            ValidateExportButton();
        }

        private void btnLoadTemplate_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.RestoreDirectory = true;
            dlg.Filter = "Excel File|*.xlsx";
            dlg.Title = "Select a test templare file";

            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                _templatePath = dlg.FileName;

                using (var excel = new ExcelPackage())
                {
                    using (var str = new FileStream(_templatePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        excel.Load(str);

                        cbxWorksheets.Items.Clear();
                        cbxWorksheets.Items.Add("Select worksheet");

                        foreach (var sheet in excel.Workbook.Worksheets)
                        {
                            cbxWorksheets.Items.Add(sheet.Name);
                        }

                        if (cbxWorksheets.Items.Contains(Settings.DefaultSpotTestWorkSheetName))
                        {
                            cbxWorksheets.SelectedItem = Settings.DefaultSpotTestWorkSheetName;
                        }

                        cbxWorksheets.Enabled = true;
                        txtRowNumber.Enabled = true;
                        txtSourceUrlColumnName.Enabled = true;
                        txtTargteUrlColumnName.Enabled = true;
                        _templateLoaded = true;
                    }
                }
            }
            ValidateExportButton();
        }

        private void txtRowNumber_Validating(object sender, CancelEventArgs e)
        {
            int rowNumber = -1;

            bool isNumeric = int.TryParse(txtRowNumber.Text, out rowNumber);

            if (isNumeric)
            {
                txtRowNumber.ForeColor = SystemColors.ControlText;
                e.Cancel = false;
            }
            else
            {
                txtRowNumber.ForeColor = Color.Red;
                e.Cancel = true;
            }

        }

        private void txtSourceUrlColumnName_Validating(object sender, CancelEventArgs e)
        {
            if (txtSourceUrlColumnName.Text.All(c => char.IsLetter(c)))
            {
                txtSourceUrlColumnName.ForeColor = SystemColors.ControlText;
                e.Cancel = false;
            }
            else
            {
                txtSourceUrlColumnName.ForeColor = Color.Red;
                e.Cancel = true;
            }
        }

        private void txtTargteUrlColumnName_Validating(object sender, CancelEventArgs e)
        {
            if (txtTargteUrlColumnName.Text.All(c => char.IsLetter(c)))
            {
                txtTargteUrlColumnName.ForeColor = SystemColors.ControlText;
                e.Cancel = false;
            }
            else
            {
                txtTargteUrlColumnName.ForeColor = Color.Red;
                e.Cancel = true;
            }
        }

        private void cbxWorksheets_SelectedIndexChanged(object sender, EventArgs e)
        {
            ValidateExportButton();
        }

        private void ValidateExportButton()
        {
            int val = 0;
            int.TryParse(txtTestCoverage.Text, out val);

            if (val > 0 && val <= 100 && _templateLoaded && cbxWorksheets.SelectedIndex != 0)
            {
                btnExport.Enabled = true;
            }
            else
            {
                btnExport.Enabled = false;
            }
        }
    }

    internal class Settings : BasicSettings
    {
        static Settings()
        {
            _sectionName = "SpotTestFormSettings";
        }

        public static string DefaultSpotTestWorkSheetName { get { return GetSetting("DefaultSpotTestWorkSheetName"); } }
        public static string DefaultStartRowNumber { get { return GetSetting("DefaultStartRowNumber"); } }
        public static string DefaultSourceUrlColumnName { get { return GetSetting("DefaultSourceUrlColumnName"); } }
        public static string DefaultTargetUrlColumnName { get { return GetSetting("DefaultTargetUrlColumnName"); } }

    }
}
